package com.linran.javaweb.advice;

import com.linran.javaweb.vo.WebResult;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;


import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

@ControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 用来处理bean validation异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public WebResult resolveConstraintViolationException(ConstraintViolationException ex) {
        WebResult errorWebResult = new WebResult(WebResult.FAILED);
        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
        if (!CollectionUtils.isEmpty(constraintViolations)) {
            StringBuilder msgBuilder = new StringBuilder();
            for (ConstraintViolation constraintViolation : constraintViolations) {
                msgBuilder.append(constraintViolation.getMessage()).append(",");
            }
            String errorMessage = msgBuilder.toString();
            if (errorMessage.length() > 1) {
                errorMessage = errorMessage.substring(0, errorMessage.length() - 1);
            }
            errorWebResult.setInfo(errorMessage);
            return errorWebResult;
        }
        errorWebResult.setInfo(ex.getMessage());
        return errorWebResult;
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public WebResult resolveMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        WebResult errorWebResult = new WebResult(WebResult.FAILED);
        List<String> errorMessageList = Optional.ofNullable(ex)
                .map(MethodArgumentNotValidException::getBindingResult)
                .map(BindingResult::getFieldErrors).orElse(Collections.emptyList()).stream()
                //对FieldError类，c+s+a+U进行查看结构
                .map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(errorMessageList)) {
            errorWebResult.setInfo(String.join(",", errorMessageList));
            return errorWebResult;
        }
        errorWebResult.setInfo(Optional.ofNullable(ex).map(MethodArgumentNotValidException::getMessage).orElse(null));
        return errorWebResult;
    }
}
